package com.mz.mattress.client.service.impl;

import com.mz.mattress.api.aliyun.OssUtil;
import com.mz.mattress.api.common.Constants;
import com.mz.mattress.api.common.Result;
import com.mz.mattress.api.entity.Device;
import com.mz.mattress.api.entity.SysFile;
import com.mz.mattress.api.enums.DeviceOptionEnum;
import com.mz.mattress.api.enums.FilePathEnum;
import com.mz.mattress.api.mattress.OpenClientApi;
import com.mz.mattress.api.mattress.req.InspectionReq;
import com.mz.mattress.api.util.StringTools;
import com.mz.mattress.client.mapper.DeviceMapper;
import com.mz.mattress.client.service.DeviceService;
import com.mz.mattress.client.util.WxQrcodeUtil;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

@Slf4j
@Service
public class DeviceServiceImpl implements DeviceService {

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private OpenClientApi openClientApi;

    @Autowired
    private WxQrcodeUtil wxQrcodeUtil;

    @Autowired
    private OssUtil ossUtil;

    @Override
    public Result<Device> info(String deviceCode) {

        Device device = deviceMapper.selectByDeviceCode(deviceCode);

        //如果不在线，需要发送指令去查询下状态
        if (device != null && device.getOnline() != 1) {
            openClientApi.queryStatus(deviceCode, device.getProductKey());
        }

        return Result.ok(device);
    }

    @Override
    public Result<Device> queryStatus(String deviceCode) {

        Device device = deviceMapper.selectByDeviceCode(deviceCode);
        if (device == null) {
            return Result.fail("找不到设备信息");
        }

        openClientApi.queryStatus(deviceCode, device.getProductKey());

        return Result.ok(device);
    }

    @Override
    public void start(String deviceCode, String productKey) {
        openClientApi.sendOptions(deviceCode, productKey, DeviceOptionEnum.start, null);
    }

    @Override
    public void pause(String deviceCode, String productKey) {
        openClientApi.sendOptions(deviceCode, productKey, DeviceOptionEnum.pause, null);
    }

    @Override
    public void end(String deviceCode, String productKey) {
        openClientApi.sendOptions(deviceCode, productKey, DeviceOptionEnum.stop, null);
    }

    @Override
    public void changeOption(String deviceCode, String productKey, DeviceOptionEnum optionEnum, Integer value) {
        openClientApi.sendOptions(deviceCode, productKey, optionEnum, value);
    }

    @Override
    public Result<String> genQrCode(Integer id) {

        Device device = deviceMapper.selectById(id);
        if (device == null) {
            return Result.fail();
        }

        if (StringTools.isNotEmpty(device.getWxUrl())) {
            return Result.ok(device.getWxUrl());
        }

//        pages/device/deviceIndex/deviceIndex?deviceCode=67738bd8353aa6e11d5c96a3
//        String code = "67738bd8353aa6e11d5c96a3";

        byte[] bytes = wxQrcodeUtil.generateQrcodeByte(device.getDeviceCode(), Constants.WX_DEVICE_PAGE, 128);

        InputStream inputStream = new ByteArrayInputStream(bytes);

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        try {
            Thumbnails.of(inputStream).size(128, 128)
                    .outputFormat("png").toOutputStream(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
            return Result.fail();
        }

        InputStream inputStream2 = new ByteArrayInputStream(outputStream.toByteArray());

        SysFile sysFile = ossUtil.uploadInputStream(inputStream2, FilePathEnum.Device, "png");

        Device update = new Device();
        update.setId(id);
        update.setWxUrl(sysFile.getUrl());
        deviceMapper.updateById(update);

        return Result.ok(sysFile.getUrl());
    }

    @Override
    public void inspection(InspectionReq req) {
        openClientApi.sendInspection(req);
    }

}
